/**
 * 
 */
package wayic.http;

import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import wayic.commons.WayicResourceEx;

/**
 * @author Ashesh Nishant
 *
 */
public abstract class AbstractHttpFetcher extends AbstractUrlLoader implements WithHttpLoader {

	@SuppressWarnings("unused")
	private final static Logger LOGGER = LogManager.getLogger(AbstractHttpFetcher.class);
	
	protected HttpLoader client;
	protected URL url;
	protected boolean conditionalGetFailed = false;
	
	/**
	 * The constructor overrides the super construction with its own defaults.
	 * Note that super() is not called. UserAgent, redirectEnabled, timeout
	 * values have alredy been set in HttpClient object and this class will provide only 
	 * read-only access to these values. 
	 */
	public AbstractHttpFetcher(HttpLoader client, URL url) throws WayicResourceEx{
		if(url == null){
			throw new WayicResourceEx("Cannot construct DefaultUrlLoader with null URL."
					, new NullPointerException("Null URL"));
		}else if(client == null){
			throw new WayicResourceEx("Cannot construct DefaultUrlLoader with null URL."
					, new NullPointerException("Null Client"));
		}
		this.client = client;
		this.url = url;
		
		super.userAgent = client.getUserAgent();
		super.redirectEnabled = client.getMaxRedirects() > 0;
		super.timeout = client.getConnectionTimeout();
	}

	/**
	 * @see wayic.feed.serv.AbstractUrlLoader#load(wayic.ContentHeader.elem.ContentHeaderI)
	 */
	public abstract ContentHeader load(ContentHeader header) throws IOException;
	
	/**
	 * @see wayic.feed.serv.AbstractUrlLoader#getUrl()
	 */
	public URL getUrl(){
		return url;
	}
	

	/**
	 * @see wayic.WithHttpLoader.serv.WithHttpClient#getHttpLoader()
	 */
	public HttpLoader getHttpLoader(){
		return client;
	}

	
	/**
	 * Override this method to return a different customized GetMethod.
	 * 
	 * @param url
	 * @param header
	 * @return
	 */
	public GetMethod newGetMethod(String url, ContentHeader header){
		HttpMethodParams params = new HttpMethodParams();
		params.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);

		GetMethod get = new GetMethod(url);
		get.setParams(params);
		setHeaders(get, header);
		conditionalGetFailed = false;
		
		return get;

	}
	
	/**
	 * Sets the request header with the etag and last-modified values of the incoming header
	 * (header from the list time this url was fetched).
	 * 
	 * @param method
	 * @param inHeader
	 * @return
	 */
	protected GetMethod setHeaders(GetMethod method, ContentHeader inHeader) {
		if (inHeader != null) {
			String etag = inHeader.getEtag();
			long modified = inHeader.getLastModified();
			if (etag != null) {
				method.setRequestHeader("If-None-Match", etag);
			}
			if (modified != ContentHeader.UNINITIALIZED) {
			    SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
		        df.setTimeZone(TimeZone.getTimeZone("GMT"));
				//An example of the field is: If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
				method.setRequestHeader("If-Modified-Since", df.format(modified));
			}
		}

		return method;
	}
	
}
